package feeinterface.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.ulwx.tool.ArrayUtils;
import com.ulwx.tool.DateTime;
import com.ulwx.tool.DbUtils;
import com.ulwx.tool.StringUtils;
import com.ulwx.type.TInteger;

import feeinterface.model.ChannelModel;
import feeinterface.modeldb.Channel;
import feeinterface.modeldb.ServiceCo;
import feeinterface.protocol.business.FeeUtil;
import feeinterface.protocol.utils.Constants;
import feeinterface.utils.DaoUtil;

/**
 * 通道操作
 * 
 * @author scj and hjf
 * 
 */
public class ChannelDao {

	private static Logger log = Logger.getLogger(ChannelDao.class);

	/**
	 * 获取所以开通的通道
	 * 
	 * @return
	 * @throws Exception
	 */
	public static List<Channel> getAll() throws Exception {
		String sql = "select * from  Channel b  where  b.Enable=1 ";
		Map<Integer, Object> map = new HashMap<Integer, Object>();
		List<Channel> list = DbUtils
				.doQueryClass(null, Channel.class, sql, map);
		return list;
	}

	/**
	 * 根据信息获取符合条件的通道
	 * 
	 * @param service
	 *            1、业务类型编码 0：不分类别 1: 月费类，2：下载类 3：游戏类 4：充值类 5：阅读类 6：音乐类; 2、业务级别编码
	 *            0：不分级别 1：A级别 2：B级别 3： C级别 4：D级别; 3、是否指定通道 1：只开放特定通道
	 *            0：按业务分类进行自动配选; 4、业务合作ID
	 * @param proviceID
	 *            省份
	 * @param cityID
	 *            地区ID，城市
	 * @param feePolicy
	 *            1: 仅限于烂通道，以实现投诉可能较高的用户扣费的控制在风险较小的通道 0 ：默认算法
	 *            此字段可以扩展，内部使用，提供给第三方的文档不会有此参数
	 * @param canSupport
	 *            需要计费中心能够返回的计费类型,用于支持应用对于付费通道的偏向性选择,客户端可以支持多种计费类型，以逗号分开。
	 *            0:表示全部支持 1：SMS 2：MMS 等等
	 * @param Carrier
	 *            运营商 移动、电信、联通、网通、铁通等
	 * @param SingleMaxFee
	 *            单次扣费限额
	 * @param phone
	 *            手机号码          
	 * @return 返回通道列表
	 * @throws Exception
	 */
	public static List<Channel> selectChannelBy(ServiceCo service,
			Integer proviceID, int cityID, String feePolicy, String canSupport,
			String Carrier, int SingleMaxFee,String phone,boolean isBelongU6) throws Exception {

		String sql = "select a.* from  Channel a  ";
		Map<Integer, Object> map = new HashMap<Integer, Object>();
		Map<Integer, Object> wheremap = new HashMap<Integer, Object>();
		int i = 0, n = 0;
		if (service.getSpecifyChannel() != Constants.SpecifyChannel.SPECIFY) {
			// ==================根据业务合作里配置的业务级别在通道表里进行筛选符合业务级别的通道
			if (service.getServiceClassCode() != null
					&& service.getServiceClassCode() > 0) {
				sql = sql
						+ " inner  join ChannelOpenServiceClass b"
						+ " on a.ChannelSno= b.ChannelID and (b.ServiceClassCode=?"
						+ " or b.ServiceClassCode=0)";// 包含适合任意业务级别的通道
				map.put(i++, service.getServiceClassCode());
			}
			// =================根据业务合作里的支持的通道业务类型在通道表里进行帅选符合相同业务类型的通道
			if (service.getServiceTypeCode() != null
					&& service.getServiceTypeCode() > 0) {
				sql = sql
						+ " inner  join ChannelOpenServiceType c"
						+ " on a.ChannelSno= c.ChannelID and (c.ServiceTypeCode=?"
						+ " or c.ServiceTypeCode=0)";// 包含适合任意业务类型的通道
				map.put(i++, service.getServiceTypeCode());
			}
		} else {
			sql = sql
					+ "INNER JOIN ServiceCoSpecifyChannel m ON a.ChannelSno= m.ChannelID AND m.ServiceCoID=?";
			map.put(i++, service.getServiceCoSno());
			log.debug("==============选取业务合作对应的指定通道==============");
		}
		String where = " where a.Enable=1  ";
		// 判断选择“未激活用户支持”的通道
		
		//2012-04-13 用户已激活的逻辑
		if (FeeUtil.getBitValue(1, feePolicy,isBelongU6) == Constants.FeePolicy.OTHERS) {
			// 1：“未激活用户支持”的通道（激活用户：表明使用过软件的用户）
			where = where + " and a.SupportUserUnUsed=1 ";
		} else {
			// 0：不支持未激活
		}
		if (!StringUtils.hasText(phone)) {
	       //是否允许为匹配手机号码的用户使用，1：允许 0：不允许
			where = where + " and a.NoPhoneUserToUse=1 ";
		}
		// ==================通道级别过滤

		// 包含请求运营商的通道
		where = where + " and a.Carrier=? ";

		wheremap.put(n++, Carrier);
		// 选择指定费率小于或等于"单次扣费限额"的通道
		if (SingleMaxFee > 0) {
			where = where + " and a.FeeCode<=?";
			wheremap.put(n++, SingleMaxFee);
		}
		// 去除在屏蔽时段内的通道
		sql = sql
				+ " inner  join ChannelOpenHour d on a.ChannelSno=d.ChannelID and "
				+ " d.OpenHour=" + new DateTime().getHours();

		// 去除在屏蔽省份的通道
		sql = sql
				+ " inner join ChannelOpenProvinceWeight e on a.ChannelSno=e.ChannelID"
				+ " and e.ProvinceID=?  and  e.Weight>0  ";

		map.put(i++, proviceID);

		// 去除屏蔽地市的通道
		where = where
				+ " and not exists(select * from ChannelCloseCity h where h.ChannelID="
				+ "a.ChannelSno and h.CityID=?)";
		wheremap.put(n++, cityID);

		// 去除合作ID被屏蔽的通道
		where = where
				+ " and not exists(select * from"
				+ " ChannelCloseServiceCo f where f.ChannelID=a.ChannelSno and "
				+ " f.ServiceCoID = ? )";
		wheremap.put(n++, service.getServiceCoSno());

		// 去除请求不支持的扣费类型（短信，wap）的通道
		// 确保0:表示全部支持的时候使用
		if (StringUtils.hasText(canSupport)) {
			String[] strs = canSupport.trim().split(",");
			if (ArrayUtils.isNotEmpty(strs)) {
				strs = ArrayUtils.trim(strs);
				try {
					Integer[] supportFeeTypes = ArrayUtils
							.StringArrayToIntegerArray(strs);
					// 孙超进 2012-02-15 去重
					supportFeeTypes = ArrayUtils
							.removeDuplicateElements(supportFeeTypes);

					if (ArrayUtils.indexOf(supportFeeTypes, 0) == -1) {// 如果找不到为0的元素
						TInteger startIndex = new TInteger(n);
						where = where
								+ " AND "
								+ DaoUtil.getSqlWherePartAndSetParms(
										"a.ChannelTypeCode in ",
										supportFeeTypes, wheremap, startIndex);
						n = startIndex.getValue();
					}
				} catch (Exception e) {
					log.error("", e);
				}
			}
		} else {
			where = where + " and (1=0) ";
		}
		// 去除通道达到最大限额的通道(日限和月限)
		sql = sql
				+ " inner join ChannelCycle g on a.ChannelSno=g.ChannelID and"
				+ "( a.ChannelDayMaxFee>g.CurDayFee or a.ChannelDayMaxFee=0)"
				+ " and ( a.ChannelMonthMaxFee>g.CurMonthFee or " +
				" a.ChannelMonthMaxFee=0 )  ";
		// 老平台在有旧版的软件出去的包是不支持短信动态验证的处理的,所以在选择通道的时候要进行判断处理.
		if (FeeUtil.getBitValue(3, feePolicy,isBelongU6) == Constants.FilterPolicy.OTHERS) {
			// 如果是短信通道，则排除动态验证的通道
			//sql = sql+ " left join ChannelSms cs on a.ChannelSno=cs.ChannelID ";
			where = where
					+ " and not exists(select * from ChannelSms cs " +
					" where a.ChannelSno=cs.ChannelID and  cs.ValidateFlag>0) ";
		}
		//第三方CP选通道要在有上行通道里选择,去除无上行通道
		if(!isBelongU6){
			where = where
					+ " and not exists(select * from ChannelSpecialWithSpNoMo cwm " +
					" where cwm.ChannelID=a.ChannelSno and cwm.TypeID=1) ";
		}
		sql = sql + " " + where;
		sql = sql + " order by e.Weight desc ";

		if (!wheremap.isEmpty()) {
			for (Integer key : wheremap.keySet()) {
				map.put(i + key, wheremap.get(key));
			}
		}
		List<Channel> list = DbUtils
				.doQueryClass(null, Channel.class, sql, map);
		return list;

	}

	public static List<ChannelModel> getChannelByRemoveOverDayMonthLimt(
			 Integer[] channelids, Integer provinceID)
			throws Exception {

		Map<Integer, Object> map = new HashMap<Integer, Object>();
		int n = 0;
		String sql = "select a.*,e.Weight as weight from Channel a"
				+ " inner join ChannelOpenProvinceWeight e on a.ChannelSno=e.ChannelID"
				+ " and e.ProvinceID=?  and  e.Weight>0   where a.Enable=1 ";

		map.put(n++, provinceID);
		TInteger startIndex = new TInteger(n);
		sql = sql
				+ " AND "
				+ DaoUtil.getSqlWherePartAndSetParms("a.ChannelSno  in ",
						channelids, map, startIndex);
		n = startIndex.getValue();
		
		sql=sql+" order by e.Weight desc";


		List<ChannelModel> rlist = DbUtils.doQueryClass(null,
				ChannelModel.class, sql, map);
		return rlist;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
